package com.hkts.flow.core.service.flowable.impl;


import com.dragon.tools.common.ReturnCode;
import com.dragon.tools.pager.PagerModel;
import com.dragon.tools.pager.Query;
import com.dragon.tools.vo.ReturnVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hkts.flow.api.flowable.ProcessDefinitionQueryVo;
import com.hkts.flow.api.flowable.ProcessNodesVo;
import com.hkts.flow.api.flowable.ret.ProcessDefinitionVo;
import com.hkts.flow.core.dao.flowable.IFlowableProcessDefinitionDao;
import com.hkts.flow.core.service.flowable.IFlowableProcessDefinitionService;
import org.apache.commons.lang.StringUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.SubProcess;
import org.flowable.bpmn.model.UserTask;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * @author : bruce.liu
 * @title: : FlowableProcessDefinitionServiceImpl
 * @projectName : flowable
 * @description: 流程定义service
 * @date : 2019/11/1314:18
 */
@Service
public class FlowableProcessDefinitionServiceImpl extends BaseProcessService implements IFlowableProcessDefinitionService {

    @Autowired
    private IFlowableProcessDefinitionDao flowableProcessDefinitionDao;

    @Override
    public PagerModel<ProcessDefinitionVo> getPagerModel(ProcessDefinitionQueryVo params, Query query) {
        Page<Object> objects = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ProcessDefinitionVo> list = flowableProcessDefinitionDao.getPagerModel(params);
        PagerModel<ProcessDefinitionVo> processDefinitionVoPagerModel = new PagerModel<>(list);
        processDefinitionVoPagerModel.setTotal(list.size());
        return processDefinitionVoPagerModel;
    }

    @Override
    public ProcessDefinitionVo getById(String processDefinitionId) {
        return flowableProcessDefinitionDao.getById(processDefinitionId);
    }

    @Override
    public ReturnVo suspendOrActivateProcessDefinitionById(String processDefinitionId, int suspensionState) {
        ReturnVo returnVo = null;
        if (suspensionState == 1){
            repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
            returnVo = new ReturnVo(ReturnCode.SUCCESS,"挂起成功");
        }else {
            repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
            returnVo = new ReturnVo(ReturnCode.SUCCESS,"激活成功");
        }
        return returnVo;
    }

    public void getLine() {

    }

    @Override
    public ProcessNodesVo getProcessNodes(ProcessDefinitionQueryVo vo, String processInstanceId) {
        Long startTime = System.currentTimeMillis();
        Page<ProcessDefinitionVo> pagerModel = flowableProcessDefinitionDao.getPagerModel(vo);
        List<ProcessDefinitionVo> result = pagerModel.getResult();
        Iterator iterator = result.iterator();
        ProcessNodesVo processNodesVo=new ProcessNodesVo();
        while (iterator.hasNext()) {
            ProcessDefinitionVo next = (ProcessDefinitionVo)iterator.next();
            if(next.getSuspensionState()==2){
                iterator.remove();
            }
        }
        if(result.size()==0){
            return null;
        }else{
            ProcessDefinitionVo processDefinitionVo=new ProcessDefinitionVo();
            for(int i=0;i<result.size();i++){
              if(processDefinitionVo.getSuspensionState()==0){
                  processDefinitionVo=result.get(i);
              }else if(processDefinitionVo.getVersion()<result.get(i).getVersion()){
                  /*
                  * 获取最高版本的流程定义
                  * */
                  processDefinitionVo=result.get(i);
              }
            }
           // processDefinitionVo.
            List<Process> processes = repositoryService.getBpmnModel(processDefinitionVo.getId()).getProcesses();
            processes.stream().forEach(process -> {
                Collection<FlowElement> flowElements = process.getFlowElements();
                if (flowElements.size()>0) {
                    for (FlowElement flowElement : flowElements) {
                        if (flowElement instanceof UserTask) {
                            System.out.println("UserTask：" + flowElement.getName());
                            processNodesVo.getTaskNames().add(flowElement.getName());
                        }
                    }
                }
            });
            processNodesVo.getTaskNames().add("结束");
           if(StringUtils.isBlank(processInstanceId)){
               processNodesVo.setCurrentTaskIndex(0);
           }else{
             //  Task task = taskService.createTaskQuery().caseInstanceId(processInstanceId).singleResult();
               Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult();
               // taskService.
               if(task!=null){
                   for(int i=0;i<processNodesVo.getTaskNames().size();i++){
                       if(processNodesVo.getTaskNames().get(i).equals(task.getName())){
                           processNodesVo.setCurrentTaskIndex(i);
                       }
                   }
               }else{
                   processNodesVo.setCurrentTaskIndex(processNodesVo.getTaskNames().size());
               }

           }
        }
        Long endTime = System.currentTimeMillis();
        Long tempTime = (endTime - startTime);
        System.out.println("定时任务花费时间："+
                (((tempTime/86400000)>0)?((tempTime/86400000)+"d"):"")+
                ((((tempTime/86400000)>0)||((tempTime%86400000/3600000)>0))?((tempTime%86400000/3600000)+"h"):(""))+
                ((((tempTime/3600000)>0)||((tempTime%3600000/60000)>0))?((tempTime%3600000/60000)+"m"):(""))+
                ((((tempTime/60000)>0)||((tempTime%60000/1000)>0))?((tempTime%60000/1000)+"s"):(""))+
                ((tempTime%1000)+"ms"));
        return processNodesVo;
    }
}
